//
// Created by lyx on 2020/8/22.
//

#include "plane_info.h"

void PlaneInfo::setViewPoint(const Vec3f &pt) {
    Vec3f view= pt - center;
    //调整z,x轴方向,注意max,min坐标的变化
    if(view.dot(zAxis)<0){
        zAxis=-zAxis;
        float zTemp=maxXYZ.z;
        maxXYZ.z=-minXYZ.z;
        minXYZ.z=-zTemp;
    }
    if(view.dot(xAxis)<0){
        xAxis=-xAxis;
        float xTemp=maxXYZ.x;
        maxXYZ.x=-minXYZ.x;
        minXYZ.x=-xTemp;
    }
    //根据右手法则调整y轴方向
    Vec3f yDirect=zAxis.cross(xAxis);
    if(yDirect.dot(yAxis)<0){
        yAxis=-yAxis;
        float yTemp=maxXYZ.y;
        maxXYZ.y=-minXYZ.y;
        minXYZ.y=-yTemp;
    }
}

void PlaneInfo::getVertices(vector<Vec3f> &pts)const {
    Vec3f xFact={xAxis[0],yAxis[0],zAxis[0]};
    Vec3f yFact={xAxis[1],yAxis[1],zAxis[1]};
    Vec3f zFact={xAxis[2],yAxis[2],zAxis[2]};
    pts.clear();
    //four coners,clock-wise=>p1,p2,p3,p4,start from left-bottom corner
    pts={{minXYZ.x,minXYZ.y,0},{minXYZ.x,maxXYZ.y,0},{maxXYZ.x,maxXYZ.y,0},{maxXYZ.x,minXYZ.y,0}};
    for(Vec3f &p:pts)p=Vec3f({xFact.dot(p),yFact.dot(p),zFact.dot(p)})+center;
}

ostream& operator << (ostream &output,const PlaneInfo &info){
    output<<info.center<<","<<info.xAxis<<","<<info.yAxis<<","<<info.zAxis<<","
          <<info.sigma<<","<<info.maxXYZ<<","<<info.minXYZ<<","<<info.ptCount<<endl;
    return output;
}

void PlaneInfo::parseLine(string line) {
    vector<string> values=lyxutils::str_utils::split_with_string_re(line,",");
    if(values.size()<22){
        std::cout<<"istream line:"<<line<<"==> is not a valid PlaneInfo record!"<<std::endl;
    }
    center.fromStringVector(values);
    xAxis.fromStringVector(values,3);
    yAxis.fromStringVector(values,6);
    zAxis.fromStringVector(values,9);
    sigma.fromStringVector(values,12);
    maxXYZ.fromStringVector(values,15);
    minXYZ.fromStringVector(values,18);
    ptCount=stoi(values[21]);
}
